﻿//==============================================================
//  Create by whl at 4/15/2014 10:55:12 AM.
//  Version 1.0
//  
//==============================================================


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cn.Finder.SDKFramework.Response;
using System.Reflection;
using Cn.Finder.SDKFramework.Attri;
using System.Collections;
using Jayrock.Json.Conversion;
using Cn.Finder.SDKFramework.Util;
using Newtonsoft.Json.Serialization;

namespace Cn.Finder.SDKFramework.Request
{
   /// <summary>
   /// 默认的Request实现 主要用于除搜索以外(添加、修改、删除)的请求
   /// </summary>
   /// <typeparam name="T"></typeparam>
    public abstract class DefaultRequest<T> : IRequest<T> where T : ApiResponse
    {
               
        
        /// <summary>
        /// 额外参数
        /// </summary>
        protected IDictionary<string, string> parameters;




        public void AddParameter(string key, string value)
        {
            if (this.parameters == null)
            {
                this.parameters = new ApiDictionary();
            }
            this.parameters.Add(key, value);

        }

        /// <summary>
        /// 获取API 接口 KEY
        /// </summary>
        /// <returns></returns>
        public abstract string GetApiName();


        /// <summary>
        /// 默认 获取请求参数   如果参数值为null 那么转成 ''
        /// </summary>
        /// <returns></returns>
        public virtual IDictionary<string, string> GetParameters()
        {

            //反射获取 请求参数字段 
            /*Type type = this.GetType();
            PropertyInfo[] propertyInfos = type.GetProperties();

            if (propertyInfos != null && propertyInfos.Length > 0)
            {
                foreach (PropertyInfo property in propertyInfos)
                {
                    RequestParameterAttribute[] theAttributes = property.GetCustomAttributes(typeof(RequestParameterAttribute), false) as RequestParameterAttribute[];

                    if (theAttributes != null && theAttributes.Length > 0)
                    {
                        string propName = "";
                  
                        RequestParameterAttribute rpa = theAttributes[0] as RequestParameterAttribute;
                        if (rpa.FieldName != null && rpa.FieldName.Trim().Length > 0)
                        {
                            propName = rpa.FieldName;
                          
                        }
                        else
                        {
                            string preStr = property.Name.Substring(0, 1).ToLower();
                            propName = preStr;
                            if (property.Name.Length > 1)
                            {
                                propName += property.Name.Substring(1);
                            }
                        }
                        object propertyValue = property.GetValue(this, null);
                       // if (propertyValue != null && propertyValue.ToString().Length > 0)
                        //if (propertyValue != null)
                        //{//如果属性值 为 null 或者空 ""， 不会发送此参数
                        //    Type propertyType = property.PropertyType;
                        //    if (propertyType.ToString().Equals("System.String"))
                        //    {
                                
                        //        AddParameter(propName, propertyValue.ToString());
                        //    }
                        //    else
                        //    {
                        //        AddParameter(propName, propertyValue.ToString());
                        //    }
                        //}

                        if (propertyValue == null)
                        {
                            propertyValue = "";
                        }
                        else if (propertyValue is DateTime)
                        {
                            DateTime pv = (DateTime)propertyValue;

                            propertyValue = pv.ToString(Constants.DATE_FORMAT);
                        }
                        else if (propertyValue is ApiObject)
                        {
                            //propertyValue = JsonConvert.ExportToString(propertyValue);
                            propertyValue = Newtonsoft.Json.JsonConvert.SerializeObject(propertyValue);
                                
                        }
                        else if (propertyValue is IList)
                        {
                            //propertyValue = JsonConvert.ExportToString(propertyValue);
                            propertyValue = Newtonsoft.Json.JsonConvert.SerializeObject(propertyValue);
                        }



                        AddParameter(propName, propertyValue.ToString());

                    }

                }
            }*/
            Type type = this.GetType();
            PropertyInfo[] propertyInfos = type.GetProperties();

            if (propertyInfos != null && propertyInfos.Length > 0)
            {
                foreach (PropertyInfo property in propertyInfos)
                {

                    Newtonsoft.Json.JsonIgnoreAttribute[] jsonIgnoreAttributes = property.GetCustomAttributes(typeof(Newtonsoft.Json.JsonIgnoreAttribute), false) as Newtonsoft.Json.JsonIgnoreAttribute[];
                    
                    if (jsonIgnoreAttributes != null && jsonIgnoreAttributes.Length > 0)
                    {
                        continue;
                    }

                    Newtonsoft.Json.JsonPropertyAttribute[] theAttributes = property.GetCustomAttributes(typeof(Newtonsoft.Json.JsonPropertyAttribute), false) as Newtonsoft.Json.JsonPropertyAttribute[];

                    string propName = "";
                    if (theAttributes == null || theAttributes.Length == 0)
                    {
                        string preStr = property.Name.Substring(0, 1).ToLower();
                        propName = preStr;
                        if (property.Name.Length > 1)
                        {
                            propName += property.Name.Substring(1);
                        }

                    }


                    else 
                    {


                        Newtonsoft.Json.JsonPropertyAttribute rpa = theAttributes[0] as Newtonsoft.Json.JsonPropertyAttribute;
                        if (rpa.PropertyName != null && rpa.PropertyName.Trim().Length > 0)
                        {
                            propName = rpa.PropertyName;

                        }
                    }
                    object propertyValue = property.GetValue(this, null);
                       

                    if (propertyValue == null)
                    {
                        propertyValue = "";
                    }
                    else if (propertyValue is DateTime)
                    {
                        DateTime pv = (DateTime)propertyValue;

                        propertyValue = pv.ToString(Constants.DATE_FORMAT);
                    }
                    else if (propertyValue is Enum)
                    {
                        propertyValue = propertyValue.ToString();
                    }
                    else if (propertyValue is EnumObject<string>)
                    {
                        propertyValue = (propertyValue as EnumObject<string>).ToString();
                    }

                    else if (propertyValue is EnumObject<int>)
                    {
                        propertyValue = (propertyValue as EnumObject<int>).ToString();
                    }
                    else if (propertyValue is EnumObject<float>)
                    {
                        propertyValue = (propertyValue as EnumObject<float>).ToString();
                    }
                    else if (propertyValue is EnumObject<double>)
                    {
                        propertyValue = (propertyValue as EnumObject<double>).ToString();
                    }

                    else if (propertyValue is ApiObject)
                    {
                        //propertyValue = JsonConvert.ExportToString(propertyValue);
                        //    propertyValue = Newtonsoft.Json.JsonConvert.SerializeObject(propertyValue);
                        IDictionary<string, string> p = new Dictionary<string, string>();

                        GetParameters(propertyValue, p);
                        propertyValue = Newtonsoft.Json.JsonConvert.SerializeObject(p);

                    }
                    else if (propertyValue is IList)
                    {
                        //propertyValue = JsonConvert.ExportToString(propertyValue);
                        //propertyValue = Newtonsoft.Json.JsonConvert.SerializeObject(propertyValue);

                        if (propertyValue == null)
                        {
                            propertyValue = "";
                        }
                        else
                        {
                            IList tmpPv = propertyValue as IList;
                            IList<IDictionary<string, string>> listDict = new List<IDictionary<string, string>>();
                            for (int k = 0; k < tmpPv.Count; k++)
                            {
                                IDictionary<string, string> p = new Dictionary<string, string>();
                                object itemObj = GetParameters(tmpPv[k], p);
                                listDict.Add(p);
                            }
                            propertyValue = Newtonsoft.Json.JsonConvert.SerializeObject(listDict);
                        }


                    }



                    AddParameter(propName, propertyValue.ToString());

                    

                }
            }

            return parameters;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="obj">对象值</param>
        /// <param name="dict">字段对象</param>
        /// <returns></returns>
        private IDictionary<string, string> GetParameters(object obj,IDictionary<string, string> dict)
        {

            Type  type = obj.GetType();

            PropertyInfo[] propertyInfos = type.GetProperties();

            if (propertyInfos != null && propertyInfos.Length > 0)
            {
                foreach (PropertyInfo property in propertyInfos)
                {

                    Newtonsoft.Json.JsonIgnoreAttribute[] jsonIgnoreAttributes = property.GetCustomAttributes(typeof(Newtonsoft.Json.JsonIgnoreAttribute), false) as Newtonsoft.Json.JsonIgnoreAttribute[];

                    if (jsonIgnoreAttributes != null && jsonIgnoreAttributes.Length > 0)
                    {
                        continue;
                    }

                    Newtonsoft.Json.JsonPropertyAttribute[] theAttributes = property.GetCustomAttributes(typeof(Newtonsoft.Json.JsonPropertyAttribute), false) as Newtonsoft.Json.JsonPropertyAttribute[];

                    string propName = "";
                    if (theAttributes == null || theAttributes.Length == 0)
                    {
                        string preStr = property.Name.Substring(0, 1).ToLower();
                        propName = preStr;
                        if (property.Name.Length > 1)
                        {
                            propName += property.Name.Substring(1);
                        }

                    }


                    else
                    {


                        Newtonsoft.Json.JsonPropertyAttribute rpa = theAttributes[0] as Newtonsoft.Json.JsonPropertyAttribute;
                        if (rpa.PropertyName != null && rpa.PropertyName.Trim().Length > 0)
                        {
                            propName = rpa.PropertyName;

                        }
                    }
                    object propertyValue = property.GetValue(obj, null);


                    if (propertyValue == null)
                    {
                        propertyValue = "";
                    }
                    else if (propertyValue is DateTime)
                    {
                        DateTime pv = (DateTime)propertyValue;

                        propertyValue = pv.ToString(Constants.DATE_FORMAT);
                    }


                    else if (propertyValue is EnumObject<string>)
                    {
                        propertyValue = (propertyValue as EnumObject<string>).ToString();
                    }

                    else if (propertyValue is EnumObject<int>)
                    {
                        propertyValue = (propertyValue as EnumObject<int>).ToString();
                    }
                    else if (propertyValue is EnumObject<float>)
                    {
                        propertyValue = (propertyValue as EnumObject<float>).ToString();
                    }
                    else if (propertyValue is EnumObject<double>)
                    {
                        propertyValue = (propertyValue as EnumObject<double>).ToString();
                    }
                    else if (propertyValue is ApiObject)
                    {

                        IDictionary<string, string> p = new Dictionary<string, string>();

                        propertyValue = GetParameters(propertyValue, p);

                    }
                    else if (propertyValue is IList)
                    {
                        //propertyValue = JsonConvert.ExportToString(propertyValue);
                        if (propertyValue == null)
                        {
                            propertyValue = "";
                        }
                        else
                        {
                            IList tmpPv = propertyValue as IList;
                            IList<IDictionary<string, string>> listDict = new List<IDictionary<string, string>>();
                            for (int k = 0; k < tmpPv.Count; k++)
                            {
                                IDictionary<string, string> p = new Dictionary<string, string>();
                                object itemObj = GetParameters(tmpPv[k], p);
                                listDict.Add(p);
                            }
                            propertyValue = Newtonsoft.Json.JsonConvert.SerializeObject(listDict);
                        }


                        
                       
                       
                    }

                    dict.Add(propName, propertyValue.ToString());

                }
            }

            return parameters;
        }


        public abstract void Validate();
    }
}
